gusucode.com > 支持向量机工具箱 - LIBSVM OSU_SVM LS_SVM源码程序 > 支持向量机工具箱 - LIBSVM OSU_SVM LS_SVM\stprtool\svm\smomat.m
function [Alpha,bias,nsv,flps]=smomat(aX,aI,aker,aarg,aC,aeps,atol,aAlpha,abias) % SMOMAT Sequential Minimal Optimization for SVM (L1). % [Alpha,bias,nsv,flps]=smomat(X,I,ker,arg,C,eps,tol,Alpha, bias) % % SMOMAT learns Support Vector Machines (L1) classifier using % Platt's Sequential Minimal Optimization algorithm. % It solves binary classification problem with linear % penalization of classification violations. % % The much more faster C-source code version of this % function is smo.c. % % Mandatory inputs: % X [NxL] L training patterns in N-dimensional space. % I [1xL] labels of training patterns (1 - 1st, 2 - 2nd class ). % ker [string] identifier of kernel, see help kernel. % arg [...] arguments of given kernel, see help kernel. % C [real] trade-off between margin and training error. % % Optional inputs: % eps [real] tolerance of KKT-conditions fulfilment (default 0.001). % tol [real] minimal change of optimized Lagrangeians (default 0.001). % Alpha [1xL] initial values of optimized Lagrangeians. If not given % then SMO starts from Alpha = zeros(1,L). % bias [real] initial value of bias. If not given then SMO starts % from bias = 0. % % Outputs: % Alpha [1xL] found Lagrangeians - solution of the SVM problem. % bias [real] found threshold of decision function (<w,x>-bias). % nsv [int] number of support vectors, i.e. number of Alpha > 0. % flps [int] number of used floating point operatins. % % See also SMO, SVMCLASS, SVM. % % Statistical Pattern Recognition Toolbox, Vojtech Franc, Vaclav Hlavac % (c) Czech Technical University Prague, http://cmp.felk.cvut.cz % Written Vojtech Franc (diploma thesis) 23.12.1999, 5.4.2000 % Modifications % 21-Oct-2001, V.Franc % 19-September-2001, V. Franc, comments changed. % 16-September-2001, V. Franc, created flops(0); global X Y Alpha b N error_cache tol eps ker arg C; Y = itosgn(aI); % transform labels (1,2) onto (1,-1) N = size(aX,2); % number of traning patterns error_cache = zeros(1,N); % initn error cache % process the input variables if nargin < 9, abias = 0; % threshold end if nargin < 8, % use given Lagrangeians or set them to zeros aAlpha = zeros(1,N); end if nargin < 7, % tolerance of KKT-conditions fulfilment for each atol = 0.001; % pattern end if nargin < 6, % minimal change in lagrangeian aeps = 0.001; end % set global variables and clear the locals X=aX; b = abias; Alpha=aAlpha; tol = atol; eps = aeps; arg = aarg; ker = aker; C = aC; clear aX aAlpha atol aeps aarg aker aC; %------------------------------------------------------- % MAIN SMO CYCLE %------------------------------------------------------- numChanged = 0; examineAll = 1; while( numChanged > 0 | examineAll ~= 0 ), numChanged = 0; if( examineAll ~= 0 ), for k=1:N, numChanged = numChanged + examineExample(k); end else for k=1:N, if( Alpha(k) ~= 0 & Alpha(k) ~= 0 ), numChanged = numChanged + examineExample(k); end end end if( examineAll == 1), examineAll = 0; elseif( numChanged == 0 ), examineAll = 1; end end % while( ...) % we use the following hyperplane <w,x>-bias=0 insted of <w,x>+bias=0 bias = -b; % clear used global variables clear global X Y b N error_cache tol eps ker arg C; nsv = length(find(Alpha>0)); % number of support vectors flps = flops; % get total number of flops return; % end of SMO main cycle % ----------------------------------------------------------- % EXAMINESTEP function %------------------------------------------------------------ function result=examineExample(i1) global X Y Alpha b N error_cache tol eps ker arg C; y1 = Y(i1); alpha1 = Alpha(i1); if( alpha1 > 0 & alpha1 < C), E1 = error_cache(i1); E1 = error_cache(i1); else E1 = learned_func(i1) - y1; end r1 = y1 * E1; if((r1 < -tol & alpha1 < C) | (r1 > tol & alpha1 > 0)), i2 = -1; tmax = 0; for k=1:N, if( Alpha(k) > 0 & Alpha(k) < C), E2 = error_cache(k); temp = abs(E1 - E2); if( temp > tmax ), tmax = temp; i2 = k; end end end if( i2 >= 0 ), if( takeStep (i1, i2) ~= 0), result = 1; return; end end randShift = round(N*rand(1)); for k=1:N, i2 = mod(k-1+randShift,N)+1; % i2 = k; if( Alpha(i2) > 0 & Alpha(i2) < C), if(takeStep(i1,i2) ~= 0 ), result = 1; return; end end end randShift = round(N*rand(1)); for k=1:N, i2 = mod(k-1+randShift,N)+1; % i2 = k; if(takeStep(i1,i2) ~= 0 ), result = 1; return; end end end % if(... result=0; return; % ----------------------------------------------------------- % TAKESTEP function % ----------------------------------------------------------- function result = takeStep(i1,i2) global X Y Alpha b N error_cache tol eps ker arg C; if(i1 == i2), result = 0; return; end alpha1 = Alpha(i1); y1 = Y(i1); if( alpha1 > 0 & alpha1 < C), E1 = error_cache(i1); else E1 = learned_func(i1) - y1; end alpha2 = Alpha(i2); y2 = Y(i2); if( alpha2 > 0 & alpha2 < C), E2 = error_cache(i2); else E2 = learned_func(i2) - y2; end s = y1 * y2; if(y1 == y2), gamma = alpha1 + alpha2; if(gamma > C), L = gamma-C; H = C; else L = 0; H = gamma; end else gamma = alpha1 - alpha2; if(gamma > 0), L = 0; H = C - gamma; else L = -gamma; H = C; end end if(L == H), result = 0; return; end k11 = kernel( X(:,i1), X(:,i1), ker,arg); k12 = kernel( X(:,i1), X(:,i2), ker,arg); k22 = kernel( X(:,i2), X(:,i2), ker,arg); eta = 2 * k12 - k11 - k22; if( eta < 0 ), a2 = alpha2 + y2 * (E2 - E1) / eta; if( a2 < L ), a2 = L; elseif( a2 > H ), a2 = H; end else c1 = eta/2; c2 = y2 * (E1-E2)- eta * alpha2; Lobj = c1 * L * L + c2 * L; Hobj = c1 * H * H + c2 * H; if( Lobj > Hobj+eps ), a2 = L; elseif( Lobj < Hobj-eps ), a2 = H; else a2 = alph2; end end if( a2 < 1e-8), a2 = 0; elseif( a2 > C- 1e-8), a2 = C; end if( abs( a2-alpha2 ) < eps*(a2+alpha2+eps)), result = 0; return; end a1 = alpha1 - s * (a2 - alpha2); if( a1 < 0 ), a2 = a2 + s * a1; a1 = 0; elseif( a1 > C ), t = a1-C; a2 = a2 + s * t; a1 = C; end if( a1 > 0 & a1 < C ), bnew = b + E1 + y1 * (a1 - alpha1) * k11 + y2 * (a2 - alpha2) * k12; elseif( a2 > 0 & a2 < C), bnew = b + E2 + y1 * (a1 - alpha1) * k12 + y2 * (a2 - alpha2) * k22; else b1 = b + E1 + y1 * (a1 - alpha1) * k11 + y2 * (a2 - alpha2) * k12; b2 = b + E2 + y1 * (a1 - alpha1) * k12 + y2 * (a2 - alpha2) * k22; bnew = (b1 + b2) / 2; end delta_b = bnew - b; b = bnew; t1 = y1 * (a1-alpha1); t2 = y2 * (a2-alpha2); for i=1:N, if( 0 < Alpha(i) & Alpha(i) < C ), error_cache(i) = error_cache(i) + t1 * kernel(X(:,i1),X(:,i),ker,arg) + ... t2 * kernel(X(:,i2),X(:,i),ker,arg) - delta_b; error_cache(i1) = 0.; error_cache(i2) = 0.; end end Alpha(i1) = a1; Alpha(i2) = a2; result = 1; return; %----------------------------------------------------------- % Compute a value of the learned decision function for % given patetrn of index k %----------------------------------------------------------- function result = learned_func(k) global X Y Alpha b N error_cache tol eps ker arg C; result = 0.; for i=1:N, if( Alpha(i) > 0), result = result + Alpha(i)*Y(i)*kernel(X(:,i),X(:,k),ker,arg); end end result = result - b; return; % EOF